package com.tgy.jwt;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.InvalidClaimException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.tgy.result.ResultObj;

import java.util.Calendar;
import java.util.Map;

public class JWTUtils {

    private static final String TOKEN = "tianguiyintoken!@#$%^&*";  //签名

    /**
     * 生成token，已传入的map集合的形式
     * @param map  //传入payload,把map中便利存入
     * @return 返回token
     */
    public static String getTokenOfMap(Map<String,String> map){
        //创建JWT builder
        JWTCreator.Builder builder = JWT.create();
        //1.设置Heard JWT推荐使用HS256算法，type只能使用JWT,所以header一般不做设置 "alg": "HS256","typ": "JWT"
        /*Map<String, Object> headerMap = new HashMap<>();
        headerMap.put("alg","HS256");
        headerMap.put("typ","JWT");
        builder.withHeader(headerMap);*/
        //2.设置Payload，json信息
        map.forEach((k,v)->{
            builder.withClaim(k,v);
        });
        //设置过期时间
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE,1);      //1天
        builder.withExpiresAt(instance.getTime());
        //3.生成Signature默认使用HMAC256算法
//        String sign = builder.sign(Algorithm.HMAC256(TOKEN));
        return builder.sign(Algorithm.HMAC256(TOKEN));
    }

    /**
     * 生成token,已json对象的形式
     * @param name  //传入name,jsonString对应的k
     * @param jsonString  //传入payload,json字符串
     * @return 返回token
     */
    public static String getTokenOfJSON(String name,String jsonString,int minute){
        //设置过期时间
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND,minute);
        return JWT.create()
                //2.设置Payload，json信息
                .withClaim(name,jsonString)
                //设置过期时间
                .withExpiresAt(instance.getTime())
                //3.生成Signature默认使用HMAC256算法
                .sign(Algorithm.HMAC256(TOKEN));
    }

    /**
     * 验证token
     * @param token
     * @return DecodedJWT
     */
    public static ResultObj verify(String token){
        try {
            JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);
            return ResultObj.JWT_SUCCESS;
        } catch (TokenExpiredException e) {
            return ResultObj.TOKEN_ERROR;
        } catch (SignatureVerificationException e){
            return ResultObj.SIGNATURE_ERROR;
        } catch (AlgorithmMismatchException e){
            return ResultObj.ALGORITHM_ERROR;
        } catch (InvalidClaimException e){
            return ResultObj.PAYLOAD_ERROR;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultObj.JWT_ERROR;
        }
    }

    /**
     * 获取token中payload
     * @param token
     * @return Object
     */
    public static <T> T getTokenPayload (String name,String token,Class<T> tClass){
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);
        String jsonString = verify.getClaim(name).asString();
        return JSON.parseObject(jsonString,tClass);
    }


}
